package com.szwistar.common.jnlua;

import com.szwistar.common.comm.CommEndpoint;
import com.szwistar.common.datastruct.JsonMapper;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.SocketAddress;
import java.nio.charset.Charset;

/**
 * LuaRpc 连接端点
 * 一个连接端点可以是到服务器的P2P连接，也可以一个服务器accept的一个连接
 * @author 张勇
 */
public class LuaRpcEndpoint implements CommEndpoint {
	protected static final Logger LOG = LoggerFactory.getLogger(LuaRpcEndpoint.class);
	protected IoSession session;
	protected Object context;

	public static ProtocolCodecFilter getFilter(String encode, String decodingDelimiter, String encodingDelimiter) {
        // 设置编解码器
    	if(encode == null) { encode = "UTF-8"; }
    	if(encodingDelimiter == null) { encodingDelimiter = LineDelimiter.UNIX.getValue(); }
    	if(decodingDelimiter == null) { decodingDelimiter = LineDelimiter.AUTO.getValue(); }

    	TextLineCodecFactory codecFactory = new TextLineCodecFactory(Charset.forName(encode), encodingDelimiter, decodingDelimiter);
    	codecFactory.setDecoderMaxLineLength(500*1024);
    	codecFactory.setEncoderMaxLineLength(10*1024);

        return new ProtocolCodecFilter(codecFactory);
	}

	@Override
	public IoSession getSession() {
		return session;
	}

	@Override
	public void close() {
		if(session == null) { return; }
		if(session.isConnected()) {	session.close(true); }
		session = null;
	}

	@Override
	public SocketAddress getLocalAddress() {
		if(session == null) { return null; }
		return session.getLocalAddress();
	}

	@Override
	public SocketAddress getPeerAddress() {
		if(session == null) { return null; }
		return session.getRemoteAddress();
	}

	@Override
	public WriteFuture write(Object message) {
		if(session == null) { return null; }
		return session.write(message);
	}

	@Override
	public boolean isConnected() {
		if(session == null) { return false; }
		return session.isConnected();
	}

	@Override
	public void onCreate(IoSession session, Object context) throws Exception {
		this.session = session;
		this.context = context;
	}

	@Override
	public void onOpened() {
	}

	@Override
	public void onMessageSent(Object message) {
	}

	@Override
	public void onMessageReceived(Object message) {
		//LOG.debug(message.toString());
		try {
			String script = message.toString();
			Object ret = ThreadLocalLuaState.get().execLua(script);
			if(ret != null) {
				// 把执行结果返回给对方？？
				session.write(JsonMapper.toJson(ret));
			}
		} catch (Exception e) {
			LOG.error("执行Lua代码失败！", e);
			// 把错误信息返回给对方？？
			session.write("\r\n" + e.toString() + "\r\n");
		}
	}

	@Override
	public void onClosed() {
		session = null;
	}

	@Override
	public void onIdle(IdleStatus status) {
	}

	@Override
	public void onExceptionCaught(Throwable cause) {
	}
}
